﻿/*
 * BList
 * 
 * Author: snowdreamist
 * Date: 2011/11/19
 * 
 */

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BitTorrentSharp.BEncoding
{
    public class BList : BValue, IList<BValue>
    {
        public BList() { }

        #region private

        private List<BValue> _internalList = new List<BValue>();

        #endregion

        #region IList

        public int IndexOf(BValue item)
        {
            return this._internalList.IndexOf(item);
        }

        public void Insert(int index, BValue item)
        {
            this._internalList.Insert(index, item);
        }

        public void RemoveAt(int index)
        {
            this._internalList.RemoveAt(index);
        }

        public BValue this[int index]
        {
            get
            {
                return this._internalList[index];
            }
            set
            {
                this._internalList[index] = value;
            }
        }

        public void Add(BValue item)
        {
            this._internalList.Add(item);
        }

        public void Clear()
        {
            this._internalList.Clear();
        }

        public bool Contains(BValue item)
        {
            return this.Contains(item);
        }

        public void CopyTo(BValue[] array, int arrayIndex)
        {
            this._internalList.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return this._internalList.Count; }
        }

        bool ICollection<BValue>.IsReadOnly
        {
            get { return ((ICollection<BValue>)this._internalList).IsReadOnly; }
        }

        public bool Remove(BValue item)
        {
            return this._internalList.Remove(item);
        }

        public IEnumerator<BValue> GetEnumerator()
        {
            return this._internalList.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return ((System.Collections.IEnumerable)this._internalList).GetEnumerator();
        }

        #endregion

        #region overrides

        internal protected override void InternalDeserialize(BinaryReader reader)
        {
            var topChar = (char)reader.PeekChar();
            if (topChar != 'l')
                throw new BEncodingException(string.Format("Not a list, input {0}", topChar));

            this._internalList.Clear();
            reader.ReadChar();

            while (reader.PeekChar() != 'e')
            {
                var value = BValue.Deserialize(reader);
                this._internalList.Add(value);
            }

            // read e
            reader.ReadChar();
        }

        internal protected override void InternalSerialize(BinaryWriter writer)
        {
            writer.Write((byte)'l');
            this.SerializeContent(writer);
            writer.Write((byte)'e');
        }

        protected internal override void InternalSerializeContent(BinaryWriter writer)
        {
            foreach (var item in this._internalList)
                item.Serialize(writer);
        }

        #endregion
    }
}
